<!DOCTYPE html
          PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html   xmlns   = "http://www.w3.org/1999/xhtml">
<head>
<link rel="STYLESHEET" href="filtersdk.css" type="text/css" />
<title>Getting Started With Audio - AviSynth</title>
</head>
<BODY>

<div id="body">

<h1>Getting started with audio</h1>

<p>The best filters to take a look at if you are searching for a way to get
  started with an audio filter is the
  <a href="http://avisynth2.cvs.sourceforge.net/avisynth2/avisynth/src/audio/">internal audio filters</a>
  of AviSynth. Mainly
  <a href="http://avisynth2.cvs.sourceforge.net/avisynth2/avisynth/src/audio/audio.cpp?view=markup"><code>audio.cpp</code></a>
  is interesting.</p>

<p>Basically you override GetAudio(...) instead of GetFrame, and fill the
  buffer with data. A simple filter could look like this:</p>
<h4>Filter creation - skip if no audio:</h4> 
<pre>
AVSValue __cdecl HalfVolume::Create(AVSValue args, void*, IScriptEnvironment* env) {
  if (!args[0].AsClip()->GetVideoInfo().AudioChannels())
    return args[0];

  return new HalfVolume(args[0].AsClip());
}
</pre>
<h4>Constructor:</h4>
<pre>
HalfVolume::HalfVolume(PClip _child)
    : GenericVideoFilter(ConvertAudio::Create(_child, SAMPLE_INT16 | SAMPLE_FLOAT, SAMPLE_FLOAT)) {   
}
</pre>
<p>This is a bit tricky. It'll require you to include
  <a href="http://avisynth2.cvs.sourceforge.net/avisynth2/avisynth/src/audio/convertaudio.cpp?view=markup"><code>ConvertAudio.cpp</code></a>. 
  What it does is automatic sample type conversion.  Basically what it does is
  that you tell that your filter supports SAMPLE_INT16 and SAMPLE_FLOAT, and
  that it prefers SAMPLE_FLOAT. If the input isn't 16 bit or float, it'll be
  converted to float.</p>
<h4>GetAudio override:</h4> 
<pre>
void __stdcall HalfVolume::GetAudio(void* buf, __int64 start, __int64 count, IScriptEnvironment* env) {
  child->GetAudio(buf, start, count, env);
  int channels = vi.AudioChannels();

  if (vi.SampleType() == SAMPLE_INT16) {
    short* samples = (short*)buf;
    for (int i=0; i< count; i++) {
      for(int j=0;j< channels;j++) {
         samples[i*channels+j] /= 2;
      }
    }
  } else if (vi.SampleType() == SAMPLE_FLOAT) {
    SFLOAT* samples = (SFLOAT*)buf;
    for (int i=0; i< count; i++) {
      for(int j=0;j< channels;j++) {
         samples[i*channels+j] /= 2.0f;
      }
    }
  }
}
</pre>
<p>Implementation of a half volume filter. Very explicit, so it isn't going to
  be the fastest possible, but it should serve the purpose. Furthermore have a look 
  <a href="http://forum.doom9.org/showthread.php?s=&threadid=72760&highlight=ConvertAudiohere">discussion here</a> 
  and look also at
  <a href="http://avisynth2.cvs.sourceforge.net/avisynth2/avisynth/src/audio/audio.cpp?view=markup"><code>audio.cpp</code></a>
  for a bunch of more advanced stuff. A lot of technical details are also to be
  found in <a href="AviSynthTwoFiveAudio.htm">AviSynth Two-Five Audio</a>.</p>
</div>
<p><kbd>$Date: 2007/07/04 00:12:07 $<br>
  Original version of this document at
  <a href="http://www.avisynth.org/GettingStartedWithAudio">http://www.avisynth.org/GettingStartedWithAudio</a>
  </kbd></p>
</BODY>
</html>
